From c68890bfaaca2fa6decfd5aa76239fff269e1128 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 24 Nov 2005 16:47:44 +0100 Subject: [PATCH] Shootdown TLB entries across all VCPUs for SMP shadow mode. Signed-off-by: Keir Fraser --- xen/arch/x86/shadow.c | 23 ++++++++--------------- xen/arch/x86/shadow32.c | 23 ++++++++--------------- xen/include/asm-x86/shadow.h | 4 ++-- 3 files changed, 18 insertions(+), 32 deletions(-) diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index c8ec769596..b339508711 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -1757,6 +1757,7 @@ static void sync_all(struct domain *d) struct out_of_sync_entry *entry; int need_flush = 0; l1_pgentry_t *ppte, opte, npte; + cpumask_t other_vcpus_mask; perfc_incrc(shadow_sync_all); @@ -1789,23 +1790,15 @@ static void sync_all(struct domain *d) unmap_domain_page(ppte); } - // XXX mafetter: SMP - // - // With the current algorithm, we've gotta flush all the TLBs - // before we can safely continue. I don't think we want to - // do it this way, so I think we should consider making - // entirely private copies of the shadow for each vcpu, and/or - // possibly having a mix of private and shared shadow state - // (any path from a PTE that grants write access to an out-of-sync - // page table page needs to be vcpu private). - // -#if 0 // this should be enabled for SMP guests... - flush_tlb_mask(cpu_online_map); -#endif + /* Other VCPUs mustn't use the revoked writable mappings. */ + other_vcpus_mask = d->cpumask; + cpu_clear(smp_processor_id(), other_vcpus_mask); + flush_tlb_mask(other_vcpus_mask); + + /* Flush ourself later. */ need_flush = 1; - // Second, resync all L1 pages, then L2 pages, etc... - // + /* Second, resync all L1 pages, then L2 pages, etc... */ need_flush |= resync_all(d, PGT_l1_shadow); #if CONFIG_PAGING_LEVELS == 2 diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index 5636840f70..8a0e81b707 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -2554,6 +2554,7 @@ void __shadow_sync_all(struct domain *d) struct out_of_sync_entry *entry; int need_flush = 0; l1_pgentry_t *ppte, opte, npte; + cpumask_t other_vcpus_mask; perfc_incrc(shadow_sync_all); @@ -2586,23 +2587,15 @@ void __shadow_sync_all(struct domain *d) unmap_domain_page(ppte); } - // XXX mafetter: SMP - // - // With the current algorithm, we've gotta flush all the TLBs - // before we can safely continue. I don't think we want to - // do it this way, so I think we should consider making - // entirely private copies of the shadow for each vcpu, and/or - // possibly having a mix of private and shared shadow state - // (any path from a PTE that grants write access to an out-of-sync - // page table page needs to be vcpu private). - // -#if 0 // this should be enabled for SMP guests... - flush_tlb_mask(cpu_online_map); -#endif + /* Other VCPUs mustn't use the revoked writable mappings. */ + other_vcpus_mask = d->cpumask; + cpu_clear(smp_processor_id(), other_vcpus_mask); + flush_tlb_mask(other_vcpus_mask); + + /* Flush ourself later. */ need_flush = 1; - // Second, resync all L1 pages, then L2 pages, etc... - // + /* Second, resync all L1 pages, then L2 pages, etc... */ need_flush |= resync_all(d, PGT_l1_shadow); if ( shadow_mode_translate(d) ) need_flush |= resync_all(d, PGT_hl2_shadow); diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index 84ad6a1a94..eeee01107f 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -596,8 +596,8 @@ update_hl2e(struct vcpu *v, unsigned long va) if ( need_flush ) { perfc_incrc(update_hl2e_invlpg); - // SMP BUG??? - local_flush_tlb_one(&linear_pg_table[l1_linear_offset(va)]); + flush_tlb_one_mask(v->domain->cpumask, + &linear_pg_table[l1_linear_offset(va)]); } } } -- 2.30.2